import urllib.request
#from ua_ip_lib import *

import urllib.request
import random
import re

ua_pool = [
    #Chrome｜谷歌浏览器
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36",
    #Firefox｜火狐浏览器
    "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0",
    #Opera｜欧朋浏览器
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36 OPR/37.0.2178.32",
    #Safari｜苹果浏览器
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2",
    #360极速浏览器
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36",
    #360安全浏览器
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36",
    #微软 Edge 浏览器
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586",
    #Internet Explorer 11 浏览器
    "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko",
    #Internet Explorer 10 浏览器
    "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)",
    #Internet Explorer 9 浏览器
    "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)",
    #Internet Explorer 8 浏览器
    "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0)",
    #百度浏览器
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 BIDUBrowser/8.3 Safari/537.36",
    #遨游浏览器
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.9.2.1000 Chrome/39.0.2146.0 Safari/537.36",
    #QQ浏览器
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36 Core/1.47.277.400 QQBrowser/9.4.7658.400",
    #UC浏览器电脑版
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 UBrowser/5.6.12150.8 Safari/537.36",
    #搜狗浏览器"
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36 SE 2.X MetaSr 1.0",
    #猎豹浏览器
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.154 Safari/537.36 LBBROWSER",
    #世界之窗浏览器
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36 TheWorld 7",
    ]

def user_agent():
    ua_pool_list = list(ua_pool)
    ua = random.choice(ua_pool)    
    index = ua_pool_list.index(ua)
    if(0 == index):
        print("\t\t正在使用浏览器：Chrome｜谷歌浏览器")
    elif(1 == index):
        print("\t\t正在使用浏览器：Firefox｜火狐浏览器")
    elif(2 == index):
        print("\t\t正在使用浏览器：Opera｜欧朋浏览器")
    elif(3 == index):
        print("\t\t正在使用浏览器：Safari｜苹果浏览器")
    elif(4 == index):
        print("\t\t正在使用浏览器：360极速浏览器")
    elif(5 == index):
        print("\t\t正在使用浏览器：360安全浏览器")
    elif(6 == index):
        print("\t\t正在使用浏览器：微软 Edge 浏览器")
    elif(7 == index):
        print("\t\t正在使用浏览器：Internet Explorer 11 浏览器")
    elif(8 == index):
        print("\t\t正在使用浏览器：Internet Explorer 10 浏览器")
    elif(9 == index):
        print("\t\t正在使用浏览器：Internet Explorer 9 浏览器")
    elif(10 == index):
        print("\t\t正在使用浏览器：Internet Explorer 8 浏览器")
    elif(11 == index):
        print("\t\t正在使用浏览器：百度浏览器")
    elif(12 == index):
        print("\t\t正在使用浏览器：遨游浏览器")
    elif(13 == index):
        print("\t\t正在使用浏览器：QQ浏览器")
    elif(14 == index):
        print("\t\t正在使用浏览器：UC浏览器电脑版")
    elif(15 == index):
        print("\t\t正在使用浏览器：搜狗浏览器")
    elif(16 == index):
        print("\t\t正在使用浏览器：猎豹浏览器")
    elif(17 == index):
        print("\t\t正在使用浏览器：世界之窗浏览器")    
    return ua

def url_catch_ua_only(url):
    opener = urllib.request.build_opener()
    #添加用户代理
    ua = user_agent()
    headers = ("User-Agent",ua)
    opener.addheaders = [headers]
    #安装为全局
    urllib.request.install_opener(opener)

    try:
        print("\t\t正在请求数据 ......")
        data = urllib.request.urlopen(url,timeout=10).read()
        return data
    except Exception as err:
        print("\t\t出现错误："+str(err))
        return str.encode("")


#爬取频道页每一页的数据,page取值从 1 开始
def get_channel_data_by_page(key_word,page):
    key_name = urllib.request.quote(key_word)
    #https://search.jd.com/Search?keyword=耳机&enc=utf-8&wq;=耳机&page=2
    url = "https://search.jd.com/Search?keyword="+key_name+"&enc=utf-8&wq;="+key_name+"&page="+str(page+1)
    print("\n\n#########################################################################")
    print("关键字：【"+str(key_word)+"】当前爬取第【"+str(page)+"】页，网址为："+str(url))
    data = url_catch_ua_only(url).decode("utf-8","ignore")
    #urllib.request.urlretrieve(url,"aaa.html")
    #print(len(data))
    if(len(data) == 0):
        return ""
    return data

#从页面中获取 商品名称 列表
def get_prd_name_from_data(data):
    pat_name = '<div class="p-name p-name-type-2">.*?<a target=".*?" title=".*?" href=".*? onclick=".*?">.*?<em>(.*?)</em>'
    name_list = re.compile(pat_name,re.S).findall(data)
    #进一步提取 商品名称:去掉无关字符
    for i in range(0,len(name_list)):
        name_list[i] = name_list[i].replace('<font class="skcolor_ljg">',"")
        name_list[i] = name_list[i].replace('</font>  ',"")
        name_list[i] = name_list[i].replace('</font>',"")
        name_list[i] = name_list[i].replace('<span class="p-tag" style="background-color:#c81623">',"")
        name_list[i] = name_list[i].replace('</span>',"")
    return name_list    

#从页面中获取 商品价格 列表
def get_prd_price_from_data(data):
    pat_price = '<strong class="J_.*?" data-done=".*?"><em>￥</em><i>(.*?)</i></strong>'
    price_list = re.compile(pat_price,re.S).findall(data)
    return price_list

    
#从页面中获取 商品ID 列表
def get_prd_ID_from_data(data):
    pat_id = '<strong class="J_(.*?)"'
    id_list = re.compile(pat_id,re.S).findall(data)
    return id_list

#进到商品的链接地址，去爬取商家信息
#<a href="//kasan.jd.com" target="_blank" title="卡三家居专营店" clstag="shangpin|keycount|product|dianpuname2_卡三家居专营店">卡三家居专营店</a>
def get_shop_name_from_url(url):
    print("爬取商品的出售方 ......")
    #data = urllib.request.urlopen(url).read().decode("utf-8","ignore")
    data = url_catch_ua_only(url).decode("gbk","ignore")
    pat = 'clstag="shangpin\|keycount\|product\|dianpuname2_.*?">(.*?)</a>'
    rst = re.compile(pat).findall(data)
    if(len(rst) != 0):
        return rst[0]
    else:
        return str("JD自营")

#从页面中获取 商品出售方 列表(这个方式非常慢，要把30个全部爬完后才能显示)
def get_prd_sales_from_data(data):
    id_list = get_prd_ID_from_data(data)
    #根据商品 ID 生成 商品的链接地址
    sales_list = []
    for i in range(0,len(id_list)):
        #商品链接
        #1、可以通过正则查找 pat_link = '<div class="p-name p-name-type-2">.*?<a target=".*?" title=".*?" href="(.*?)"'
        #2、也可以根据商品ID构造，是一样的，虽然链接不一样，但实际重定向后的地址是一样的,这种方法更高效省时
        prd_url = "http://item.jd.com/"+str(id_list[i])+".html"
        #进到商品的链接地址，去爬取商家信息
        sales = get_shop_name(prd_url)
        sales_list.append(sales)
    return sales_list

#根据商品 ID 生成 商品的链接地址,最后调用 get_shop_name_from_url  获取 商品出售方(这个方式避开对首页data的处理，要快一些) 
def get_prd_url(id_p):
    #商品链接
    #1、可以通过正则查找 pat_link = '<div class="p-name p-name-type-2">.*?<a target=".*?" title=".*?" href="(.*?)"'
    #2、也可以根据商品ID构造，是一样的，虽然链接不一样，但实际重定向后的地址是一样的,这种方法更高效省时
    prd_url = "http://item.jd.com/"+str(id_p)+".html"
    #cefp进到商品的链接地址，去爬取商家信息
    #sales = get_shop_name(prd_url)
    return prd_url

#从页面中获取 商品评论数量 列表
def get_prd_cmt_cnt_from_data(data):
    pat_cmt_cnt = '">(.*?)</a>条评价</strong>'
    cmt_cnt_list = re.compile(pat_cmt_cnt).findall(data)
    return cmt_cnt_list

#根据商品ID，生成该商品每一页评论的链接地址(通过抓包方法分析)，page表示第几页评论，从1开始
#http://sclub.jd.com/comment/productPageComments.action?&productId=13394586810&score=0&sortType=5&page=2&pageSize=10
def get_commnet_url(prd_id,page):
    url = "http://sclub.jd.com/comment/productPageComments.action?&productId="+str(prd_id)+"&score=0&sortType=5&page="+str(page-1)+"&pageSize=10"
    return url
    
#获取评论：根据商品的ID，爬取评论内容(通过抓包方法分析)，page_cnt是要爬取的页数限制
def get_comment(prd_id,page_cnt):
    cmt_list = []
    #print("爬取商品的评论 ......")
    for page in range(1,page_cnt+1):
        #首先找到评论的链接地址
        cmt_url = get_commnet_url(prd_id,page)
        data = url_catch_ua_only(cmt_url).decode("gbk","ignore")
        pat = '"id":.*?,"guid":".*?","topped":.*?,"content":"(.*?)",'
        print("正在爬取第【"+str(page)+"】页的评论，地址是："+str(cmt_url))
        rst = re.compile(pat,re.S).findall(data)
        if(len(rst) != 0):
            for i in range(0,len(rst)):
                #将评论一一追加
                cmt_list.append(rst[i])
                
    return cmt_list
    


keyword = "耳机"
#要求爬取的页数
page_cnt = 40

def run():
    for page_channel in range(1,page_cnt+1):
        data = get_channel_data_by_page(keyword,page_channel)
        if(len(data) == 0):
            print("爬取出错，数据为空")
            return
        else:        
            name_list = get_prd_name_from_data(data)
            price_list = get_prd_price_from_data(data)
            id_list = get_prd_ID_from_data(data)
            #sales_list = get_prd_sales_from_data(data)
            cmt_cnt_list = get_prd_cmt_cnt_from_data(data)

        if( 0==len(name_list) or 0==len(price_list) or 0==len(id_list) or 0==len(cmt_cnt_list) ):
            print("爬取出错,部分条目未爬取到")
            return
        else:
            item_cnt = len(name_list)
            if(len(price_list) != item_cnt):
               print("爬取出错,价格数量 和 商品名称数量不相等")
               return
            elif(len(id_list) != item_cnt):
               print("爬取出错,ID数量 和 商品名称数量不相等")
               return
            elif(len(cmt_cnt_list) != item_cnt):
               print("爬取出错,评论数量 和 商品名称数量不相等")
               return

        print("\n当前页面(第"+str(page_channel)+"页)共用有 "+str(item_cnt)+" 项商品")        
        for index in range(0,item_cnt):
            name = name_list[index]
            price = price_list[index]
            #sales = sales_list[index]
            id_p = id_list[index]            
            cmt_cnt = cmt_cnt_list[index]       
             
            print("\n----------第【"+str(index+1)+"】项商品的信息如下-------------")
            print("商品名称:  "+str(name))
            print("商品价格： "+str(price))
            sales = get_shop_name_from_url(get_prd_url(id_p))
            print("售卖商店： "+str(sales))
            print("商品ID  ： "+str(id_p))
            print("评论数量： "+str(cmt_cnt))

            fh = open("data\\common.txt","a+")
            fh.write("【商品名称】:  "+str(name)+"\t")
            fh.write("【商品价格】： "+str(price)+"\t")
            fh.write("【售卖商店】： "+str(sales)+"\t")
            fh.write("【商品ID  】： "+str(id_p)+"\t")
            fh.write("【评论数量】： "+str(cmt_cnt)+"\t")
            fh.write("\n")
            fh.close()
            
            print("该项商品的评论信息如下：")
            #默认爬取的评论的页数
            cmt_page_cnt = 2
            comment_list = get_comment(id_p,cmt_page_cnt)
            if(len(comment_list) == 0):
                print("没有评论")
            else:
                fh_c = open("data\\comment_id_"+str(id_p)+".txt","w")
                for index_cmt in range(0,len(comment_list)):
                    print("评论【"+str(index_cmt+1)+"】："+str(comment_list[index_cmt]))
                    fh_c.write("评论【"+str(index_cmt+1)+"】："+str(comment_list[index_cmt])+"\n")
                fh_c.close()

run()



                
